﻿using System.Collections.Generic;

using Basis;

using DG.Tweening;

using NL.Combat;

using UnityEngine;

namespace NL.Advanced
{
    [System.Serializable]
    public class _ATTData
    {
        public string name;
        public float Power;

    }

    // ????Ч??
    public enum AttackEffect
    {
        None = 0,
        Power = 1,
        //伤害.
        Hurt = 11,
        //治疗
        Heal = 32,
        BuffAdd = 31,
        BuffRemove = 32,

        BeatBack = 41,//击退

        Skill= 51,

        Ice = 110,//冰冻
        Fire = 120,//火伤
        Bomb = 130,//爆炸
        Dizz = 140, //眩晕
        Sput = 150,//溅射

        Power_Fire = 201,//火属性伤害
        Power_Electric = 202,//电属性伤害
        Power_Ice = 203,//冰属性伤害

        Power_Bomb_Hurt = 1300,//爆炸伤害
        Power_Frozen_Hurt = 1100,//冰冻伤害
        Power_Dizz_Hurt = 1400,//眩晕伤害
        Power_Sput_Hurt = 1500,//溅射伤害
    };

    public enum AttackDataSource
    {
        Fixed = 0,

        Owner = 1,


        Target = 11,
    }

    public enum AttackType
    {
        P_Normal = 0,
        P_Fire = 1,
        P_Electric = 2,
        P_Ice = 3,
    }


    public interface IAttacker
    {
        bool ShowUI { get; set; }
        //AttackerResult Attack(ICombatOwner who, float ed, float factor);
        //AttackerResult Attack(ICombatOwner who, float factor);
        AttackerResult Attack(ICombatOwner who);
        bool CanAttack(ICombatOwner who);
    }
    public interface IAttackerOwner
    {
        GameObject gameObject { get; }
        ICombatOwner CombatOwner { get; }

        void SetCombat(ICombatOwner _owner, BB _bb);
        BB BBOwner { get; }
    }

    public struct AttackerResult
    {
        public bool Avilable;
        public string Message;
        public int Buff;
        public AttackerResult(string _err)
        {
            Avilable = string.IsNullOrEmpty(_err);
            Buff = 0;
            Message = _err;
        }
        public AttackerResult(int _buff)
        {
            Avilable = true;
            Buff = _buff;
            Message = "";
        }
    }

    public struct AttackerInfo
    {
        public AttackEffect Effect;
        public AttackType Type;
        public float ED;
        public float Factor;
        public int Stage;
    }

    public enum AttackerWorkState
    {
        Standalone = 1,
        Additive = 2,
    }

    public interface ILauncherGenerater
    {
        GameObject GetLauncher(int id);
    }

    public partial class Attacker : MonoBehaviour, IAttacker, ITagOwner, ITagFilter
    {
        [SerializeField]
        private HashSet<string> _Tags = new HashSet<string>();
        public HashSet<string> Tags
        {
            get => _Tags;
        }


        public void ParseTag(string _str)
        {
            ITagOwnerEx.ParseTag(_str, ref _Tags);
        }

        public bool TargetValid(ITagOwner _target)
        {
            return ITagOwnerEx.TargetValid(this, _target);
        }

        public bool HasValidTarget(IList<GameObject> _objs)
        {
            foreach (var obj in _objs)
            {
                var owner = obj.GetComponent<ITagOwner>();
                if (owner == null)
                    continue;
                if (TargetValid(owner))
                    return true;
            }

            return false;
        }

        public string InitStr = "";


        [Header("有效性,阵营有效")]
        public CampType AvliableCamp = CampType.Enemy;

        [Header("攻击伤害效果")]
        public AttackEffect EffectMode = AttackEffect.Power;

        [Header("使用攻击法球得后缀..Orb_Ice_Flying_XXX")]
        public string Orbsuffix;

        [Header("伤害数值 固定值;基于英雄;基于目标.")]
        public AttackDataSource DataSource = AttackDataSource.Owner;

        [Header("表达式: (x,y)属性条目语法;  (buffid,bufftime)buff语法 ;(x,y,z)位移语法")]
        public string Data = "";//会有多条数据叠加

        [Header("基础伤害增强系数 factor)")]
        public float Factor = 1;
        [Header("目标数量，-1表示所有目标")]
        public int TargetCont = -1;
        [Header("伤害段数，1段，2段...")]
        public int Section = 1;

        [Header("有效次数;正对同一目标的有效次数")]
        public int AttackOnce = -1;
        public int AttackOnceOnTarget = -1;



        int _AttackCount = 0;
        Dictionary<ICombatOwner, int> _AttactCountOnTarget = new Dictionary<ICombatOwner, int>();

        public AttackerWorkState WorkState;

        bool _Disposable = false;

        AnnexData _Annex;


        protected ICombatOwner _CombatOwner;
        public ICombatOwner CombatOwner => _CombatOwner;

        protected GameObject _LauncherOwner;
        public GameObject LauncherOwner => _LauncherOwner;

        protected BB _Owner;
        public BB Owner => _Owner;

        protected PropertyCC _LauncherProperty;
        public Attacker SetBBOwner(BB _bb)
        {
            _Owner = _bb; return this;
        }
        public Attacker SetEffectMode(AttackEffect effect)
        {
            EffectMode = effect; return this;
        }
        public Attacker SetAvliableCamp(CampType camp)
        {
            AvliableCamp = camp; return this;
        }
        public Attacker SetDataSource(AttackDataSource ds)
        {
            DataSource = ds; return this;
        }
        public Attacker SetData(string data)
        {
            Data = data; return this;
        }
        public Attacker SetFactor(float factor)
        {
            Factor = factor; return this;
        }
        public Attacker SetSection(int section)
        {
            Section = section; return this;
        }
        protected virtual void Awake()
        {


        }

        bool __STARTED = false;
        protected virtual void Start()
        {
            OnLive();
            __STARTED = true;
        }

        void OnEnable()
        {
            if (!__STARTED) return;

            OnLive();
        }
        public static void CLEAR_HashBoard()
        {
            CountLiving = 0; CountLived = 0; CountDead = 0;
        }
        public static int CountLiving;
        public static int CountLived;
        public static int CountDead;


        protected virtual void OnLive()
        {
            CountLived++;

            CountLiving++;

            _AttackCount = 0;
            _AttactCountOnTarget.Clear();


            _Owner = GetComponent<BB>();

            if (_CombatOwner == null)
                _CombatOwner = _Owner != null ? _Owner.CombatOwner : null;

            _LauncherProperty = null;
            if (_Owner != null)
            {
                _LauncherOwner = _Owner.LauncherOwner;

                _LauncherProperty = GetLauncherPropertyFromLauncher(_LauncherOwner);
            }


            _LoadFromInfo();


            _AddOrbFlying();

            _Annex = Data;

            if (WorkState == AttackerWorkState.Additive)
            {
                bool AddToOther = false;
                //向上叠加
                var all = GetComponents<Attacker>();
                foreach (var a in all)
                {
                    if (this.Equals(a) == false && CanCombine(a) == true)
                    {
                        a.AddAttacker(_Annex, Data);
                        AddToOther = true;
                        break;

                    }
                }
                if (AddToOther)
                {
                    Destroy(this);
                }
            }
        }

        public virtual Attacker AddAttacker(AnnexData OtherAnnex, string OtherData)
        {
            _Annex += OtherAnnex;
            // 之前是Data得字符相加,在之后伤害逻辑得时候 在数学化
            // Data = $"{Data}{NLConst.CHAR_ARRAY}{OtherData}";
            try
            {
                Vector4 data1 = ((nill)Data).AsVector4(NLConst.CHAR_INNER);
                Vector4 data2 = ((nill)OtherData).AsVector4(NLConst.CHAR_INNER);
                Vector4 data = data1 + data2;

                Data = $"{data.x}{NLConst.CHAR_INNER}{data.y}{NLConst.CHAR_INNER}{data.z}{NLConst.CHAR_INNER}{data.w}{NLConst.CHAR_INNER}";
            }catch
            {
                Data = $"{Data}{NLConst.CHAR_ARRAY}{OtherData}";
            }


            return this;
        }
        protected virtual bool CanCombine(Attacker other)
        {
            return EffectMode.Equals(other.EffectMode)
                && AvliableCamp.Equals(other.AvliableCamp)
                && DataSource.Equals(other.DataSource)
                && Section.Equals(other.Section);

        }

        protected virtual PropertyCC GetLauncherPropertyFromLauncher(GameObject launcherOwner)
        {
            return launcherOwner != null && launcherOwner.GetComponent<PropertyCC>() != null ? launcherOwner.GetComponent<PropertyCC>() : null;
        }

        void OnDisable()
        {
            CountDead++;
            CountLiving--;

            _OrbFlying?.SetActive(false);

            if (_Disposable)
                Destroy(this);
        }
        public string _PropertyStr;
        private NLIni _Info;

        protected virtual void _LoadFromInfo()
        {
            if (CombatSetting.LOGable)
                LOG.Add($"[Arracker._LoadFromInfo] :{InitStr} ");
            if (string.IsNullOrEmpty(InitStr))
                return;
            _Info = new NLIni(InitStr, NLConst.CHAR_ARRAY);


            //攻击效果
            EffectMode = _Info["type"].AsEnumer<AttackEffect>(AttackEffect.None);

            switch (EffectMode)
            {
                case AttackEffect.BuffAdd:
                    break;
                case AttackEffect.Power:
                case AttackEffect.Power_Fire:
                case AttackEffect.Power_Electric:
                case AttackEffect.Power_Ice:
                case AttackEffect.Power_Frozen_Hurt:
                case AttackEffect.Power_Bomb_Hurt:
                case AttackEffect.Power_Dizz_Hurt:
                case AttackEffect.Power_Sput_Hurt:
                case AttackEffect.Hurt:
                case AttackEffect.BeatBack:
                    AvliableCamp = CampType.Enemy; break;
                case AttackEffect.Heal:
                    AvliableCamp = CampType.Friend; break;

                default:
                    AvliableCamp = CampType.All; break;
            }

            //发球后缀.
            Orbsuffix = _Info["Orbsuffix"].ToString(Orbsuffix);

            //数值来源
            DataSource = _Info["source"].AsEnumer<AttackDataSource>(AttackDataSource.Owner);
            Data = _Info["data"].ToString("");

            Factor = _Info["factor"].AsFloatDefault(Factor);

            Section = _Info["section"].AsIntDefault(Section);

            WorkState = _Info["work"].AsEnumer<AttackerWorkState>(AttackerWorkState.Standalone);

            //读取 攻击部有效次数(不分目标)
            AttackOnce = _Info["once"].AsIntDefault(AttackOnce);
            
            //读取 攻击部针对某目标的 有效次数
            AttackOnceOnTarget = _Info["once_target"].AsIntDefault(AttackOnceOnTarget);

            //有效阵营
            if (_Info.Has("camp"))
                AvliableCamp = _Info["camp"].AsEnumer<CampType>(CampType.Enemy);




            _PropertyStr = _Info.ToString(NLConst.CHAR_ARRAY, "type", "source", "data", "camp", "tag");

            var tagStr = _Info["tag"].AsString;
            ParseTag(tagStr);


            if (CombatSetting.LOGable)
                LOG.Add($"[Arracker._LoadFromInfo] :EffectMode:{EffectMode}   DataSource:{DataSource}  Data:{Data}  ");
        }

        public bool CanAttack(ICombatOwner who)
        {
            if (who.Equals(null))
                return false;
            var tagOwner = who.gameObject.GetComponent<ITagOwner>();
            if (tagOwner != null)
            {
                if (!TargetValid(tagOwner))
                {
                    return false;
                }
            }

            if (_CombatOwner == null || _CombatOwner.gameObject == null)
                return false;

            if (!Camp.ISCampOf(AvliableCamp, _CombatOwner, who))
                return false;



            return true;
        }

        // 施加 效果..同时增加 给 who 的一个运行时 buff
        //  来自 语句表达式 之外的 属性条目..
        // type=hurt;data=0,0.5; source=target ;multi=2,0; att=20;
        // 其中 multi=2,0; att=20; 将被以 运行时 buff的形式添加..
        // 注意: Attacker 生命周期
        // 1... 技能的 Effect..在Skill._DoLaunchBegin() 时候添加,在 _DoLauncherEnd() 之后移除
        // 2... 技能的 Attacker..在 攻防计算前 时候添加,在  攻防计算 之后移除
        public bool ShowUI { get; set; }

        public AttackerResult Attack(ICombatOwner who)
        {
            return Attack(who, Factor);
        }
        public AttackerResult Attack(ICombatOwner who, float factor)
        {
            return Attack(who, 0, factor);
        }

        public AttackerResult Attack(ICombatOwner who, float ed, float factor)
        {



            if (AttackOnce > 0 && _AttackCount >= AttackOnce)
            {
                if (CombatSetting.LOGable)
                    LOG.Add("[Attacker.Attack]error:Avilible=false");
                return new AttackerResult("[Attacker.Attack]error:_AttackCount >= AttackOnce");
            }

            if (AttackOnceOnTarget > 0)
            {
                if (_AttactCountOnTarget.ContainsKey(who) && _AttactCountOnTarget[who] >= AttackOnceOnTarget)
                {
                    return new AttackerResult("[Attacker.Attack]error:_AttactCountOnTarget[who] >= AttackOnceOnTarget");
                }
            }


            if (who.Equals(null))
            {
                if (CombatSetting.LOGable)
                    LOG.Add("[Attacker.Attack] error who=null");
                return new AttackerResult("[Attacker.Attack] error who=null");
            }

            var tagOwner = who.gameObject.GetComponent<ITagOwner>();
            if (tagOwner != null)
            {
                if (!TargetValid(tagOwner))
                {
                    var result = new AttackerResult();
                    result.Avilable = false;
                    if (CombatSetting.LOGable)
                        LOG.Add("[Attacker.Attack] error TargetValid()=false");
                    return result;
                }
            }

            var attowner = GetComponent<IAttackerOwner>();
            _CombatOwner = attowner != null ? attowner.CombatOwner : null;

            if (_CombatOwner == null || _CombatOwner.Equals(null) || _CombatOwner.gameObject == null)
            {
                if (CombatSetting.LOGable)
                    LOG.Add("[Attacker.Attack] error _CombatOwner=null");
                // return;
            }

            if (_CombatOwner != null && !_CombatOwner.Living)
            {
                if (CombatSetting.LOGable)
                    LOG.Add("[Attacker.Attack] error: CombatOwner.Living=false");
            }

            if (!Camp.ISCampOf(AvliableCamp, _CombatOwner, who))
            {
                if (CombatSetting.LOGable)
                    LOG.Add("[Attacker.Attack]AvliableCamp NONONONON ");
                return new AttackerResult("[Attacker.Attack]AvliableCamp NONONONON");
            }

            // 属性效果 添加
            int skillbuff = string.IsNullOrEmpty(_PropertyStr) ? 0 : who.AddAnnexs(InitStr);

            //if(Combate.ISEnemy(_CombatOwner,who) && who.UnitStateInclude(UnitStateMask.behitno))
            //{
            //    LOG.Add("[Attacker.Attack]AvliableCamp NONONONON ");
            //    // return new AttackerResult("[Attacker.Attack]who.CanBeHit == false");
            //    return new  AttackerResult(skillbuff);
            //}

            //LOG.Add($"[Arracker.Attack({who.gameObject})] :{EffectMode} --{Data} ");

            switch (EffectMode)
            {
                case AttackEffect.Power:
                case AttackEffect.Power_Fire:
                case AttackEffect.Power_Electric:
                case AttackEffect.Power_Ice:
                case AttackEffect.Power_Bomb_Hurt:
                case AttackEffect.Power_Sput_Hurt:
                case AttackEffect.Power_Dizz_Hurt:
                case AttackEffect.Power_Frozen_Hurt:
                    _DoAttack(who, _GenerateAttProperty(ed, factor));
                    break;
                case AttackEffect.Hurt:
                    _DoHurt(who, ed, factor);
                    break;

                case AttackEffect.Heal:
                    _DoHeal(who, factor);
                    break;
                case AttackEffect.BuffAdd:
                    _DoBuffAdd(who, factor);
                    break;

                case AttackEffect.BeatBack:
                    _DoBeatBack(who, factor);
                    break;
                case AttackEffect.Ice:
                    _DoIce(who, factor);
                    break;
                case AttackEffect.Bomb:
                    _DoBomb(who, factor);
                    break;
                case AttackEffect.Dizz:
                    _DoDizz(who, factor);
                    break;
                case AttackEffect.Sput:
                    _DoSput(who, factor);
                    break;
                case AttackEffect.Skill:
                    _DoSkill();
                    break;
            }
            _AttackCount++;

            if (_AttactCountOnTarget.ContainsKey(who))
                _AttactCountOnTarget[who]++;
            else
                _AttactCountOnTarget.Add(who, 1);


            return new AttackerResult(skillbuff);
        }


        protected ATT _CombineAttData(ICombatOwner target, AttackerInfo _AttProperty)
        {
            ATT att;
            switch (DataSource)
            {
                case AttackDataSource.Owner:
                    att = _CombatOwner != null ? _CombatOwner.GenarateAtt(_LauncherProperty, _AttProperty) : ATT.Zero;
                    break;
                case AttackDataSource.Target:
                    att = target == null ? target.GenarateAtt(null, _AttProperty) : ATT.Zero;
                    break;
                default:
                    att = _CombatOwner != null ? _CreateZeroATT(_CombatOwner,_AttProperty) : ATT.Zero;
                    break;
            }

            // 复合 攻击部的攻击力.
            if (!string.IsNullOrEmpty(Data))
            {
                string[] attlist = CreateDataList();
                if (attlist != null && attlist.Length > 0)
                {
                    foreach (var item in attlist)
                    {
                        att.AddAttack(item);
                    }
                }
            }

            return att;
        }

        protected virtual ATT _CreateZeroATT(ICombatOwner target, AttackerInfo _AttProperty)
        {
            return ATT.Zero;
        }

        protected string[] CreateDataList()
        {
            string[] attlist = null;
            if (!string.IsNullOrEmpty(Data))
            {
                attlist = Data.Split(NLConst.CHAR_ARRAY);
            }

            return attlist;
        }

        // 攻防 模式  factor 放大倍数  默认是1.
        protected virtual void _DoAttack(ICombatOwner who, AttackerInfo _AttProperty)
        {

            //if(who.UnitStateInclude(UnitStateMask.behitno))
            //    return;


            //合成攻击力
            ATT att = _CombineAttData(who, _AttProperty);



            //获取 目标防御数据
            DENF denf = who.GenarateDefence(_AttProperty.Effect);


            //攻防计算...

            //Debug.Log($"伤害结算:ATT目标:{_CombatOwner} ===> DENF目标:{who}");

            //计算伤害.....
            HURT _hurt = att.AttackAt(denf);

            ////应用子弹得 factor
            //_hurt.life *= _Owner.Factor;

            //应用子弹得 factor
            if (_Owner != null) _hurt.life *= _Owner.Factor;


            if (CombatSetting.LOGable)
                LOG.Add($"[Attacker._DoAttack]{(_CombatOwner!=null?_CombatOwner.UDD:0)}->{who.UDD}:{_hurt}");

            // 对目标 结算伤害....
            who.HitBy(_hurt, _CombatOwner, _Owner != null && _Owner.LauncherOwner != null ? _Owner.LauncherOwner : null);

            _CombatOwner?.Hit(_hurt, who, _Owner != null && _Owner.LauncherOwner != null ? _Owner.LauncherOwner : null);

        }

        // 直接伤害模式
        protected virtual void _DoHurt(ICombatOwner who, float ed, float _factor = 1)
        {

            float dhp = 0;
            switch (DataSource)
            {
                case AttackDataSource.Fixed:
                    dhp = _Annex.Value;
                    break;
                case AttackDataSource.Owner:
                    dhp = _CombatOwner != null ? _CombatOwner.HP * (1 + _Annex.Factor) + _Annex.Point : _Annex.Value;
                    break;
                case AttackDataSource.Target:
                    dhp = who.HP * _Annex.Factor + _Annex.Point;
                    break;
            }
            dhp *= _factor;



            //应用子弹得 factor
            if (_Owner != null) dhp *= _Owner.Factor;

            // 要考虑 _CombatOwner 为空.(比如场景的天然 陷阱光环等BB).
            //var hurtEx = new HURT()//(true, dhp, false, _CombatOwner==null? AttackType.Physics: _CombatOwner.AttackType);
            //{
            //    life = dhp,
            //    //type = _CombatOwner == null ? AttackType.Physics : _CombatOwner.AttackType
            //};

            var hurtEx = _CreateHurt(who, dhp);


            if (CombatSetting.LOGable)
                LOG.Add($"[Attacker._DoHurt]{(_CombatOwner != null ? _CombatOwner.UDD : 0)}->{who.UDD}:{hurtEx}");

            //_FixHurt(_who, hurtEx);

            //hurtEx.ShowUI = ShowUI;

            who.HitBy(hurtEx, _CombatOwner, _Owner != null && _Owner.LauncherOwner != null ? _Owner.LauncherOwner : null);

            _CombatOwner?.Hit(hurtEx, who, _Owner != null && _Owner.LauncherOwner != null ? _Owner.LauncherOwner : null);

        }

        protected virtual HURT _CreateHurt(ICombatOwner who,float life)
        {
            return new HURT()//(true, dhp, false, _CombatOwner==null? AttackType.Physics: _CombatOwner.AttackType);
            {
                life = Mathf.FloorToInt(life),
                //type = _CombatOwner == null ? AttackType.Physics : _CombatOwner.AttackType
            };
        }

        // 治疗模式
        protected virtual void _DoHeal(ICombatOwner who, float _factor = 1)
        {

            float dhp = 0;

            var baseVal = 0f;
            var atkPercent = 0f;
            var tarPercent = 0f;

            if (!string.IsNullOrEmpty(Data))
            {
                string[] attlist = CreateDataList();
                if (attlist != null && attlist.Length > 0)
                {
                    foreach (var item in attlist)
                    {
                        var arr = item.Split(NLConst.CHAR_INNER);
                        if (arr.Length > 0)
                        {
                            baseVal += float.Parse(arr[0]);
                        }

                        if (arr.Length > 1)
                        {
                            atkPercent += float.Parse(arr[1]);
                        }

                        if (arr.Length > 2)
                        {
                            tarPercent += float.Parse(arr[2]);
                        }
                    }
                }
            }



            dhp = baseVal + _CombatOwner.GenarateAtt().point * atkPercent + who.HP * tarPercent;

            dhp *= _factor;

            //应用子弹得 factor
            if (_Owner != null) dhp *= _Owner.Factor;

            //var heal = new HEAL();
            //heal.life = dhp;
            



            var heal = _CreateHeal(who, dhp);


            if (CombatSetting.LOGable)
                LOG.Add($"[Attacker._DoHeal]{(_CombatOwner != null ? _CombatOwner.UDD : 0)}->{who.UDD}:{heal}");


            //heal.ShowUI = ShowUI;
            who.HealBy(heal, _CombatOwner);
        }

        protected virtual HEAL _CreateHeal(ICombatOwner who, float life)
        {
            return new HEAL()//(true, dhp, false, _CombatOwner==null? AttackType.Physics: _CombatOwner.AttackType);
            {
                life = Mathf.FloorToInt(life),
                //type = _CombatOwner == null ? AttackType.Physics : _CombatOwner.AttackType
            };
        }

        void _DoBuffAdd(ICombatOwner who, string _Data, float _factor = 1)
        {
            if (who == null || who.gameObject == null || !who.Living)
                return;
            if (_factor == 0)
                return;




        }

        // BUFF 模式
        protected virtual void _DoBuffAdd(ICombatOwner who, float _factor = 1)
        {
            if (!string.IsNullOrEmpty(Data))
            {
                string[] attlist = CreateDataList();
                if (attlist != null && attlist.Length > 0)
                {
                    foreach (var item in attlist)
                    {
                        var data = ((nill)item).AsVector(NLConst.CHAR_INNER);

                        int buffid = (int)data.x;
                        float life = data.y;

                        if (buffid < 0) continue;


                        if (CombatSetting.LOGable)
                            LOG.Add($"[Attacker._DoBuffAdd]{(_CombatOwner != null ? _CombatOwner.UDD : 0)}->{who.UDD}:{buffid},{life}");

                        who.ADDBuff(buffid, life)?.SetCombat(_CombatOwner, _Owner);
                    }
                }
            }

        }

        //物理 反馈模式.
        protected virtual void _DoBeatBack(ICombatOwner who, float _factor = 1)
        {
            Vector3 dd = Vector3.zero;

            if (!string.IsNullOrEmpty(Data))
            {
                string[] attlist = CreateDataList();
                if (attlist != null && attlist.Length > 0)
                {
                    foreach (var item in attlist)
                    {
                        var delt = ((nill)item).AsVector(NLConst.CHAR_INNER);

                        switch (DataSource)
                        {
                            case AttackDataSource.Fixed:
                                dd += delt; break;
                            case AttackDataSource.Owner:
                                if (_CombatOwner != null) dd += _CombatOwner.transform.TransformVector(delt); break;
                            case AttackDataSource.Target:
                                if (who != null) dd += who.transform.TransformVector(delt); break;
                            default:
                                break;
                        }
                    }
                }
            }

            var pos = who.transform.position;
            float YY = pos.y;
            who.transform.DOMove(pos + dd, 0.2f).onComplete = () =>
            {
                if (dd.y > 0)
                {
                    who.transform.DOMoveY(YY, 0.1f);
                }
            };

            if (CombatSetting.LOGable)
                LOG.Add($"[Attacker._DoBeatBack]{(_CombatOwner != null ? _CombatOwner.UDD : 0)}->{who.UDD}:{dd}");
        }

        protected virtual GameObject _DoSkill()
        {
            GameObject NewLaunch = null;
            int skid = int.Parse(Data);

            if(skid > 0)
            {
                GameObject Mod = CombatOwner.GetLauncher(skid);

                if (Mod != null)
                {
                    NewLaunch = this.ADDNewLaunch(Mod, transform.position, null);
                }
            }
            if (CombatSetting.LOGable)
                LOG.Add($"[Attacker._DoSkill]{(_CombatOwner != null ? _CombatOwner.UDD : 0)}{skid}");

            return NewLaunch;
        }

        public Attacker SetShowUI(bool _show)
        {
            ShowUI = _show;
            return this;
        }
        public Attacker Set(string _init)
        {
            InitStr = _init;

            return this;
        }
        //public Attacker Set(string _init,List<FixEx> _fixes)
        //{
        //    InitStr = _init;
        //    Fixes = _fixes;
        //    return this;
        //}

        public Attacker SetDisposable(bool _dispose)
        {
            _Disposable = _dispose; return this;
        }

        protected virtual AttackerInfo _GenerateAttProperty(float ed, float factor)
        {
            AttackerInfo _Property = new AttackerInfo()
            {
                Effect = EffectMode,
                ED = ed,
                Factor = factor,
                Stage = Section,
            };

            return _Property;
        }

        //public void AttackEnd()
        //{
        //    if(gameObject != null && gameObject.activeInHierarchy)
        //    {
        //        Destroy(this);
        //    }
        //}

        protected AnnexData GetAnnex()
        {
            return _Annex;
        }
    }

    public static class AttackerExtends
    {
        public static GameObject GetLauncher(this ICombatOwner who,int id)
        {
            if (who == null) return null;
            ILauncherGenerater launcherOwner = who.gameObject.GetComponentInParent<ILauncherGenerater>();

            if (launcherOwner == null) return null;

            return launcherOwner.GetLauncher(id);
        }
    }
}

